/************************************************************************/
/* @file            gxParam.h                                           */
/* @brief           gxParam                                             */
/* @version         2013.11.14 johnxguo created                         */
/************************************************************************/

#ifndef __GX_PARAM_H_INCLUDED__
#define __GX_PARAM_H_INCLUDED__

#include "IGxParam.h"
#include "gxMap.h"

namespace gx
{
namespace base
{
class CGxParam : public IGxParam
{
public:
    CGxParam(void);
    ~CGxParam(void);

    bool SetBool(const String& strKey, bool bVal);
    bool SetU8(const String& strKey, u8 u8Val);
    bool SetS8(const String& strKey, s8 s8Val);
    bool SetC8(const String& strKey, c8 c8Val);
    bool SetU16(const String& strKey, u16 u16Val);
    bool SetS16(const String& strKey, s16 s16Val);
    bool SetU32(const String& strKey, u32 u32Val);
    bool SetS32(const String& strKey, s32 s32Val);
    bool SetU64(const String& strKey, u64 u64Val);
    bool SetS64(const String& strKey, s64 s64Val);
    bool SetF32(const String& strKey, f32 f32Val);
    bool SetF64(const String& strKey, f64 f64Val);
    bool SetStr(const String& strKey, const String& strVal);
    bool SetPVoid(const String& strKey, void* pVoid);
    bool SetParam(const String& strKey, CGxPtr<IGxParam> gxpParam);

    bool GetBool(const String& strKey, bool& bVal);
    bool GetU8(const String& strKey, u8& u8Val);
    bool GetS8(const String& strKey, s8& s8Val);
    bool GetC8(const String& strKey, c8& c8Val);
    bool GetU16(const String& strKey, u16& u16Val);
    bool GetS16(const String& strKey, s16& s16Val);
    bool GetU32(const String& strKey, u32& u32Val);
    bool GetS32(const String& strKey, s32& s32Val);
    bool GetU64(const String& strKey, u64& u64Val);
    bool GetS64(const String& strKey, s64& s64Val);
    bool GetF32(const String& strKey, f32& f32Val);
    bool GetF64(const String& strKey, f64& f64Val);
    bool GetStr(const String& strKey, String& strVal);
    bool GetPVoid(const String& strKey, void*& pVoid);
    bool GetParam(const String& strKey, CGxPtr<IGxParam>& gxpParam);

    bool Remove(const String& strKey);
    bool Clear();
    bool GetBuffer(c8*& pBuf, u32& uLen);
    bool SetBuffer(c8* pBuf, u32 uLen);
    bool GetNetBuffer(c8*& pBuf, u32& uLen);
    bool SetNetBuffer(c8* pBuf, u32 uLen);

    DECLARE_REF_IMPL()

protected:
    bool Insert(const String& strKey, u8 cType, void* pVoid);
    bool Obtain(const String& strKey, u8 cType, void*& pVoid);
    template<class T> inline bool SetParamT(const String& strKey, u8 cType, T valT);
    template<class T> inline bool GetParamT(const String& strKey, u8 cType, T& valT);

private:
    u32 GetStrHash(const String& strSrc);

private:
    typedef struct
    {
        void* pVoid;
        u8 cType;
    }ParamItem;
    typedef GxMap<u32, ParamItem> MapParam;
    typedef std::pair<u32, ParamItem> PairParam;
    MapParam m_mapParam;
    void DelMapElem(MapParam::iterator it);
    
private:
    CGxMutex m_mutex;
    u32      m_uCount;
};

template<class T>
inline bool CGxParam::SetParamT( const String& strKey, u8 cType, T valT )
{
    T* p = new T(valT);
    if (Insert(strKey, cType, (void*)p))
    {
        return true;
    }

    delete p;
    return false;
}

template<class T>
inline bool CGxParam::GetParamT( const String& strKey, u8 cType, T& valT )
{
    void* pVoid = NULL;
    if (Obtain(strKey, cType, pVoid))
    {
        return false;
    }
    if (pVoid)
    {
        valT = *((T*)pVoid);
        return true;
    }

    return false;
}

}//end namespace base
}//end namespace gx

#endif
